package sm.upgrade;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.hibernate3.HibernateTemplate;

import sm.dam.api.DBDictService;
import sm.upgrade.api.DBDictUpgrade;
import sm.upgrade.api.DBDictUpgradeService;
import sm.upgrade.api.DataService;
import sm.upgrade.api.UpgradePhase;
import sm.upgrade.exception.UpgradeException;
import sm.upgrade.util.UpgradeContext;

public class DBDictUpgradeImpl implements DBDictUpgrade {

	private static Logger logger = LoggerFactory.getLogger(DBDictUpgrade.class);

	private HibernateTemplate upgradeTemplate;

	private DataService upgradeDataService;

	private DBDictUpgradeService dbdictUpgradeService;

	public DBDictUpgradeImpl(ApplicationContext customerContext,
			ApplicationContext upgradeContext) {
		dbdictUpgradeService = (DBDictUpgradeService) customerContext
				.getBean("dbdictUpgradeService");
		upgradeTemplate = (HibernateTemplate) upgradeContext
				.getBean("template");
		upgradeDataService = (DataService) upgradeContext
				.getBean("dataService");
	}

	public DBDictUpgradeImpl() {
		this(UpgradeContext.getInstance().getOrCreateCustomerContext(),
				UpgradeContext.getInstance().getOrCreateUpgradeContext());
	}

	@Override
	public void upgradeDBDict(boolean fix) {
		logger.info("Start DBDICT PHASE");
		List<Object> list = upgradeTemplate.find("select name from "
				+ DBDictService.DBDICT + " where name != ?",
				UpgradePhase.UPGRADE_RESULTS);
		if (logger.isInfoEnabled()) {
			logger.info("There are " + list.size()
					+ " dbdicts to be processed.");
		}
		for (Object obj : list) {
			String fileName = (String) obj;
			try {
				upgradeDBDict(fileName, fix);
			} catch (Exception e) {
				logger.error(
						"Error in upgrade dbdict " + fileName + ":"
								+ e.getMessage(), e);
			}
		}
		logger.info("  Finish DBDICT PHASE");
	}

	@Override
	public void upgradeDBDict(String fileName, boolean fix)
			throws UpgradeException {
		dbdictUpgradeService.upgradeDBDict(fileName, upgradeDataService, fix);
	}

	@Override
	public boolean checkDBDictChange() {
		boolean hasChange = false;
		List<Object> list = upgradeTemplate.find("select name from "
				+ DBDictService.DBDICT);

		for (Object obj : list) {
			String fileName = (String) obj;
			boolean fileHasChange = false;
			try {
				fileHasChange = checkDBDictChange(fileName);
			} catch (UpgradeException e) {
				logger.error("Error in check dbdict change of dbdict "
						+ fileName + ":" + e.getMessage(), e);
			}
			if (!hasChange) {
				hasChange = fileHasChange;
			}
		}

		return hasChange;
	}

	@Override
	public boolean checkDBDictChange(String fileName) throws UpgradeException {
		return dbdictUpgradeService.checkDBDictChange(fileName,
				upgradeDataService);
	}

	@Override
	public boolean validateData() {
		boolean hasConflict = false;
		List<Object> list = upgradeTemplate.find("select name from "
				+ DBDictService.DBDICT);

		for (Object obj : list) {
			String fileName = (String) obj;
			boolean fileHasConflict = false;
			try {
				fileHasConflict = validateData(fileName);
			} catch (UpgradeException e) {
				logger.error("Error in validate data of dbdict " + fileName
						+ ":" + e.getMessage(), e);
			}
			if (!hasConflict) {
				hasConflict = fileHasConflict;
			}
		}

		return hasConflict;
	}

	@Override
	public boolean validateData(String fileName) throws UpgradeException {
		return dbdictUpgradeService.validateData(fileName, upgradeDataService);
	}

	@Override
	public boolean validateNewKey(String fileName, boolean fix)
			throws UpgradeException {
		return dbdictUpgradeService.validateNewKey(fileName, fix,
				upgradeDataService);
	}

	@Override
	public boolean validateNewKey(boolean fix) {
		boolean hasConflict = false;
		List<Object> list = upgradeTemplate.find("select name from "
				+ DBDictService.DBDICT);

		for (Object obj : list) {
			String fileName = (String) obj;
			boolean fileHasConflict = false;
			try {
				fileHasConflict = validateNewKey(fileName, fix);
			} catch (UpgradeException e) {
				logger.error("Error in validate key of dbdict " + fileName
						+ ":" + e.getMessage(), e);
			}
			if (!hasConflict) {
				hasConflict = fileHasConflict;
			}
		}

		return hasConflict;
	}

	@Override
	public boolean validateOldKey(String fileName) throws UpgradeException {
		return dbdictUpgradeService
				.validateOldKey(fileName, upgradeDataService);
	}

	@Override
	public boolean validateOldKey() {
		boolean hasConflict = false;
		List<Object> list = upgradeTemplate.find("select name from "
				+ DBDictService.DBDICT);

		for (Object obj : list) {
			String fileName = (String) obj;
			boolean fileHasConflict = false;
			try {
				fileHasConflict = validateOldKey(fileName);
			} catch (UpgradeException e) {
				logger.error("Error in validate key of dbdict " + fileName
						+ ":" + e.getMessage(), e);
			}
			if (!hasConflict) {
				hasConflict = fileHasConflict;
			}
		}

		return hasConflict;
	}
}
